home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
doom
/
suckmods.zip
/
SUCKMODS.ZIP
/
suck05
/
src
/
weapons.qc
< prev
next >
Wrap
Text File
|
1997-05-13
|
54KB
|
2,314 lines
void(entity e, float chan, string samp, float vol, float atten) playsound;
void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
void () player_run;
void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
void(vector org, vector vel, float color, float damage) SpawnBlood;
void() SuperDamageSound;
void() HasteSound;
void() TossRune;
void() bound_other_ammo;
void() RuneTouch;
void() RuneRespawn;
void(vector org) spawn_tfog;
void(vector org, entity death_owner) spawn_tdeath;
void(entity bomb, entity attacker, float rad, entity ignore) T_DischargeDamage;
void(vector org, vector dir) launch_spike;
entity(float disp) identify_player;
void() bubble_bob;
void() InitRune;
void () regimpulse;
void () checkregimpulse;
void () PrintHelp;
void () RuneInfo;
void () GroupPowerInfo;
void () KiziTeleportToBase;
void () ShogunTeleport;
// SUCK: Print everyone's kills and deaths to the console.
void() PrintStats =
{
local entity e, guy;
local float min, last_min;
local string s;
local float done;
guy=find(world, classname, "player");
while (guy!=world)
{
sprint(self, guy.netname);
sprint(self, ": Kills: ");
s=ftos(guy.num_kills);
sprint(self, s);
sprint(self, " Deaths: ");
s=ftos(guy.num_deaths);
sprint(self, s);
sprint(self, "\n");
guy=find(guy, classname, "player");
}
return;
last_min=-9999;
done=0;
while (done!=1)
{
e=find(world, classname, "player");
min=e.num_kills;
guy=e;
while (e!=world)
{
if ((e.num_kills<=min) && (e.num_kills>=last_min))
{
guy=e;
min=e.num_kills;
}
e=find(world, classname, "player");
}
if (min==last_min)
done=1;
else
{
last_min=min;
}
}
};
// called by worldspawn
void() W_Precache =
{
precache_sound ("hknight/hit.wav"); // flamethrower
precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
precache_sound ("weapons/rocket1i.wav"); // spike gun
precache_sound ("weapons/sgun1.wav");
precache_sound ("weapons/guncock.wav"); // player shotgun
precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
precache_sound ("weapons/spike2.wav"); // super spikes
precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
precache_sound ("weapons/grenade.wav"); // grenade launcher
precache_sound ("weapons/bounce.wav"); // grenade bounce
precache_sound ("weapons/shotgn2.wav"); // super shotgun
precache_sound2 ("blob/land1.wav"); // chain go splorch!
if (cvar("teamplay") & TEAM_CAPTURE_CUSTOM) {
precache_sound ("weapons/chain1.wav");
precache_sound ("weapons/chain2.wav");
precache_sound ("weapons/chain3.wav");
precache_sound ("weapons/bounce2.wav");
}
// ZOID:
// normally the weapon models are precached in the individual item
// creation routines. But since we've added impulse 21 we can drop
// weapons at any time. Must precache all weapon models.
precache_model ("progs/g_shot.mdl");
precache_model ("progs/g_nail.mdl");
precache_model ("progs/g_nail2.mdl");
precache_model ("progs/g_rock.mdl");
precache_model ("progs/g_rock2.mdl");
precache_model ("progs/g_light.mdl");
precache_model ("progs/dog.mdl");
precache_sound ("dog/ddeath.wav");
precache_sound ("dog/dsight.wav");
};
float() crandom =
{
return 2*(random() - 0.5);
};
/*
================
W_FireAxe
================
*/
void() W_FireAxe =
{
local vector source;
local vector org;
local vector f;
if (self.rune_num == ITEM_RUNE_KIZI)
KiziTeleportToBase();
if (self.rune_num == ITEM_RUNE_SHOGUN)
ShogunTeleport();
makevectors (self.v_angle);
source = self.origin + '0 0 16';
if (self.rune_num == ITEM_RUNE_SAMURAI)
traceline (source, source + v_forward*640, FALSE, self);
else
traceline (source, source + v_forward*64, FALSE, self);
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.takedamage)
{
trace_ent.axhitme = 1;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
T_Damage (trace_ent, self, self, 80);
else if (self.rune_num == ITEM_RUNE_SAMURAI)
T_Damage (trace_ent, self, self, 60);
else
T_Damage(trace_ent, self, self, 20);
if ((self.rune_num == ITEM_RUNE_VAMPIRE) ||
(self.rune_num == ITEM_RUNE_IFRITE))
{
if (trace_ent.rune_num == ITEM_RUNE_MONK)
SpawnBlood (org, '0 0 0', 1, 50);
else
SpawnBlood (org, '0 0 0', 73, 50);
f_x=1000*random();
f_y=1000*random();
f_z=1000*random();
launch_spike(self.origin, f);
newmis.solid=SOLID_NOT;
newmis.nextthink=time+1.5;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
setmodel(newmis, "progs/w_spike.mdl");
else
setmodel(newmis, "progs/k_spike.mdl");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
f_x=1000*random();
f_y=1000*random();
f_z=1000*random();
launch_spike(self.origin, f);
newmis.solid=SOLID_NOT;
newmis.nextthink=time+1.5;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
setmodel(newmis, "progs/w_spike.mdl");
else
setmodel(newmis, "progs/k_spike.mdl");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
f_x=1000*random();
f_y=1000*random();
f_z=1000*random();
launch_spike(self.origin, f);
newmis.solid=SOLID_NOT;
newmis.nextthink=time+1.5;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
setmodel(newmis, "progs/w_spike.mdl");
else
setmodel(newmis, "progs/k_spike.mdl");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
}
if (trace_ent.rune_num == ITEM_RUNE_MONK)
SpawnBlood (org, '0 0 0', 1, 20);
else
SpawnBlood (org, '0 0 0', 73, 20);
}
else
{ // hit wall
playsound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
};
//============================================================================
vector() wall_velocity =
{
local vector vel;
vel = normalize (self.velocity);
vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
vel = vel + 2*trace_plane_normal;
vel = vel * 200;
return vel;
};
/*
================
SpawnMeatSpray
================
*/
void(vector org, vector vel) SpawnMeatSpray =
{
local entity missile, mpuff;
local vector org;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_NOT;
makevectors (self.angles);
missile.velocity = vel;
missile.velocity_z = missile.velocity_z + 250 + 50*random();
missile.avelocity = '3000 1000 2000';
// set missile duration
missile.nextthink = time + 1;
missile.think = SUB_Remove;
setmodel (missile, "progs/zom_gib.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
/*
================
SpawnBlood
================
*/
void(vector org, vector vel, float color, float damage) SpawnBlood =
{
particle (org, vel*0.1, color, damage*2);
};
/*
================
spawn_touchblood
================
*/
void(float damage) spawn_touchblood =
{
local vector vel;
vel = wall_velocity () * 0.2;
SpawnBlood (self.origin + vel*0.01, vel, 73, damage);
};
/*
================
SpawnChunk
================
*/
void(vector org, vector vel) SpawnChunk =
{
particle (org, vel*0.02, 0, 10);
};
/*
==============================================================================
MULTI-DAMAGE
Collects multiple small damages into a single damage
==============================================================================
*/
entity multi_ent;
float multi_damage;
void() ClearMultiDamage =
{
multi_ent = world;
multi_damage = 0;
};
void() ApplyMultiDamage =
{
if (!multi_ent)
return;
T_Damage (multi_ent, self, self, multi_damage);
};
void(entity hit, float damage) AddMultiDamage =
{
if (!hit)
return;
if (hit != multi_ent)
{
ApplyMultiDamage ();
multi_damage = damage;
multi_ent = hit;
}
else
multi_damage = multi_damage + damage;
};
/*
==============================================================================
BULLETS
==============================================================================
*/
/*
================
TraceAttack
================
*/
void(float damage, vector dir) TraceAttack =
{
local vector vel, org;
vel = normalize(dir + v_up*crandom() + v_right*crandom());
vel = vel + 2*trace_plane_normal;
vel = vel * 200;
org = trace_endpos - dir*4;
if (trace_ent.takedamage)
{
if (trace_ent.rune_num == ITEM_RUNE_MONK)
SpawnBlood (org, vel*0.2, 1, damage);
else
SpawnBlood (org, vel*0.2, 73, damage);
AddMultiDamage (trace_ent, damage);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
};
/*
================
FireBullets
Used by shotgun, super shotgun, and enemy soldier firing
Go to the trouble of combining multiple pellets into a single damage call.
================
*/
void(float shotcount, vector dir, vector spread) FireBullets =
{
local vector direction;
local vector src;
makevectors(self.v_angle);
src = self.origin + v_forward*10;
src_z = self.absmin_z + self.size_z * 0.7;
ClearMultiDamage ();
while (shotcount > 0)
{
direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
traceline (src, src + direction*2048, FALSE, self);
if (trace_fraction != 1.0)
TraceAttack (4, direction);
shotcount = shotcount - 1;
}
ApplyMultiDamage ();
};
void() holy_touch =
{
local string s;
if ((other.classname != "player") ||
(other.rune_num == ITEM_RUNE_VIKING))
{
remove(self);
return;
}
if ((other.team == self.owner.team) && (other.health<100))
{
other.health = other.health + 30;
if (other.health > 100) other.health = 100;
clientmsg(other, "You have been blessed by the priest.\n");
sprint(self.owner, "Priest: Name: ");
sprint(self.owner, other.netname);
sprint(self.owner, " Health: ");
s=ftos(other.health);
sprint(self.owner, s);
}
if ((other.team != self.owner.team) && (other.rune_num == ITEM_RUNE_VAMPIRE))
{ other.deathweapon = "holywater";
T_Damage(other, self, self.owner, 125);
other.deathweapon = "";
other.msg_center=1;
clientmsg(other, "The holy water burns you!\n");
self.msg_center=1;
clientmsg(self.owner, "You burn the vampire with your holy water!\n");
}
if ((other.team != self.owner.team) &&
(other.rune_num == ITEM_RUNE_WEREWOLF))
{
other.deathweapon="holywater";
T_Damage(other, self, self.owner, 50);
other.deathweapon = "";
}
if (other.team != self.owner.team)
{
other.deathweapon="holywater";
T_Damage(other, self, self.owner, 25);
other.deathweapon = "";
}
remove(self);
};
void() W_FireHolyWater =
{
local vector dir;
local entity wat;
dir=aim(self, 1000);
wat = spawn ();
wat.owner = self;
wat.movetype = MOVETYPE_FLYMISSILE;
wat.solid = SOLID_BBOX;
wat.angles = vectoangles(dir);
wat.touch = holy_touch;
wat.classname = "holywater";
wat.think = SUB_Remove;
wat.nextthink = time + 6;
setmodel (wat, "progs/s_bubble.spr");
setsize (wat, VEC_ORIGIN, VEC_ORIGIN);
setorigin (wat, self.origin+'0 0 16');
wat.velocity = dir * 1000;
};
/*
================
W_FireShotgun
================
*/
void() W_FireShotgun =
{
local vector dir;
local vector src;
local vector org;
local vector foo;
local entity e;
if ((self.rune_num == ITEM_RUNE_PRIEST) && (self.holy == 1))
{
W_FireHolyWater();
return;
}
playsound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
dir = aim (self, 100000);
if (self.rune_num == ITEM_RUNE_NINJA)
{
if (self.player_flag & ITEM_ENEMY_FLAG)
{
FireBullets(6,dir, '0.04 0.04 0');
return;
}
src = self.origin + v_forward*10;
traceline (src, src + dir*2048, FALSE, self);
if (!trace_ent.takedamage)
{
makevectors(dir);
org=self.origin-trace_endpos;
foo=normalize(org);
org=trace_endpos+(foo*55);
spawn_tfog(self.origin);
spawn_tfog(self.origin);
spawn_tfog(org);
spawn_tfog(org);
spawn_tdeath (org,self);
setorigin (self, org);
self.teleport_time = time + 1;
self.flags = self.flags - self.flags & FL_ONGROUND;
self.ideal_yaw=vectoyaw(self.angles);
self.ideal_yaw=self.ideal_yaw+180;
ChangeYaw();
self.currentammo = self.ammo_shells = self.ammo_shells + 1;
}
else
FireBullets(6, dir, '0.04 0.04 0');
}
else
FireBullets (6, dir, '0.04 0.04 0');
};
/*
================
W_FireSuperShotgun
================
*/
void() W_FireSuperShotgun =
{
local vector dir;
if (self.currentammo == 1)
{
W_FireShotgun ();
return;
}
playsound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
self.punchangle_x = -4;
self.currentammo = self.ammo_shells = self.ammo_shells - 2;
dir = aim (self, 100000);
FireBullets (14, dir, '0.14 0.08 0');
};
/*
==============================================================================
ROCKETS
==============================================================================
*/
void() s_explode1 = [0, s_explode2] {};
void() s_explode2 = [1, s_explode3] {};
void() s_explode3 = [2, s_explode4] {};
void() s_explode4 = [3, s_explode5] {};
void() s_explode5 = [4, s_explode6] {};
void() s_explode6 = [5, SUB_Remove] {};
void() BecomeExplosion =
{
self.movetype = MOVETYPE_NONE;
self.velocity = '0 0 0';
self.touch = SUB_Null;
setmodel (self, "progs/s_explod.spr");
self.solid = SOLID_NOT;
s_explode1 ();
};
void() T_MissileTouch =
{
local float damg;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
damg = 100 + random()*20;
if (self.owner.rune_num == ITEM_RUNE_SAMURAI)
damg = damg / 4;
if (other.health)
T_Damage (other, self, self.owner, damg);
// don't do radius damage to the other, because all the damage
// was done in the impact
T_RadiusDamage (self, self.owner, 120, other);
// playsound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
BecomeExplosion ();
};
/*
================
W_FireRocket
================
*/
void() W_FireRocket =
{
local entity missile, mpuff;
local vector dir;
if (self.rune_num == ITEM_RUNE_GOLOM)
return;
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
playsound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "missile";
// set missile speed
makevectors (self.v_angle);
missile.velocity = aim(self, 100000);
if (self.rune_num == ITEM_RUNE_WIND)
missile.velocity = missile.velocity * 3000;
else
missile.velocity = missile.velocity * 1000;
missile.angles = vectoangles(missile.velocity);
missile.touch = T_MissileTouch;
// set missile duration
missile.nextthink = time + 5;
missile.think = SUB_Remove;
if (self.rune_num != ITEM_RUNE_LOKI)
setmodel (missile, "progs/missile.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + v_forward*8 + '0 0 16');
if ((self.rune_num == ITEM_RUNE_VAMPIRE) ||
(self.rune_num == ITEM_RUNE_IFRITE))
{
dir = aim (self, 1000);
launch_spike(self.origin + '0 0 16', dir);
newmis.solid=SOLID_NOT;
newmis.nextthink=time+3;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
setmodel(newmis, "progs/w_spike.mdl");
else
setmodel(newmis, "progs/k_spike.mdl");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
launch_spike(self.origin - '0 0 16', dir);
newmis.solid=SOLID_NOT;
newmis.nextthink=time+3;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
setmodel(newmis, "progs/w_spike.mdl");
else
setmodel(newmis, "progs/k_spike.mdl");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
}
else if (self.rune_num == ITEM_RUNE_PRIEST)
{
dir=aim(self, 1000);
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+5;
newmis.touch=holy_touch;
setmodel(newmis, "progs/s_bubble.spr");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
newmis.velocity=newmis.velocity - (newmis.velocity * 0.1);
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+5;
newmis.touch=holy_touch;
setmodel(newmis, "progs/s_bubble.spr");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
newmis.velocity=newmis.velocity - (newmis.velocity * 0.2);
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+5;
newmis.touch=holy_touch;
setmodel(newmis, "progs/s_bubble.spr");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
newmis.velocity=newmis.velocity - (newmis.velocity * 0.3);
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+5;
newmis.touch=holy_touch;
setmodel(newmis, "progs/s_bubble.spr");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
newmis.velocity=newmis.velocity - (newmis.velocity * 0.8);
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+5;
newmis.touch=holy_touch;
setmodel(newmis, "progs/s_bubble.spr");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
newmis.velocity=newmis.velocity - (newmis.velocity * 0.82);
}
};
/*
===============================================================================
LIGHTNING
===============================================================================
*/
/*
=================
LightningDamage
=================
*/
void(vector p1, vector p2, entity from, float damage) LightningDamage =
{
local entity e1, e2;
local vector f, v;
f = p2 - p1;
normalize (f);
f_x = 0 - f_y;
f_y = f_x;
f_z = 0;
f = f*16;
e1 = e2 = world;
traceline (p1, p2, FALSE, self);
if (trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from, damage);
if (self.classname == "player")
{
if (other.classname == "player")
trace_ent.velocity_z = trace_ent.velocity_z + 400;
}
}
e1 = trace_ent;
traceline (p1 + f, p2 + f, FALSE, self);
if (trace_ent != e1 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from, damage);
}
e2 = trace_ent;
traceline (p1 - f, p2 - f, FALSE, self);
if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
{
particle (trace_endpos, '0 0 100', 225, damage*4);
T_Damage (trace_ent, from, from, damage);
}
};
void(vector p1, vector p2, entity from, float damage) TractorEffect =
{
local entity e1, e2;
local vector f;
f = p2 - p1;
normalize (f);
f_x = 0 - f_y;
f_y = f_x;
f_z = 0;
f = f*16;
e1 = e2 = world;
traceline (p1, p2, FALSE, self);
e1 = trace_ent;
if (trace_ent.takedamage && trace_ent.classname != "trigger_multiple"&& trace_ent.classname != "door")
{
trace_ent.origin = self.origin+v_forward*vlen(self.origin-trace_ent.origin);
trace_ent.movetype = MOVETYPE_TOSS;
trace_ent.nextthink = time + 0.5;
}
traceline (p1 + f, p2 + f, FALSE, self);
if (trace_ent != e1 && trace_ent.takedamage &&
trace_ent.classname != "trigger_multiple" &&
trace_ent.classname != "door")
{
trace_ent.origin = self.origin+v_forward*vlen(self.origin-trace_ent.origin);
trace_ent.movetype = MOVETYPE_TOSS;
trace_ent.nextthink = time + 0.5;
}
e2 = trace_ent;
traceline (p1 - f, p2 - f, FALSE, self);
if (trace_ent.takedamage && trace_ent != e1 && trace_ent != e2 && trace_ent.classname != "trigger_multiple" && trace_ent.classname != "door")
{
trace_ent.origin = self.origin+v_forward*vlen(self.origin-trace_ent.origin);
trace_ent.movetype = MOVETYPE_TOSS;
trace_ent.nextthink = time + 0.5;
}
};
void(vector v) ThorBoilWaterPoint =
{
local entity bubble;
// SUCK: Spawn some bubbles to make it look like the water is
// boiling.
bubble=spawn();
setmodel(bubble, "progs/s_bubble.spr");
setorigin(bubble, v);
bubble.movetype=MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity_z=45;
bubble.velocity_x=(random()*100) - 50;
bubble.velocity_y=(random()*100) - 50;
bubble.nextthink = time + 1.5;
bubble.think = SUB_Remove;
bubble.classname = "bubble";
bubble.frame = 0;
bubble.cnt = 0;
setsize(bubble, '-8 -8 -8', '8 8 8');
bubble=spawn();
setmodel(bubble, "progs/s_bubble.spr");
setorigin(bubble, v);
bubble.movetype=MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity_z=45;
bubble.velocity_x=(random()*100) - 50;
bubble.velocity_y=(random()*100) - 50;
bubble.nextthink = time + 1.5;
bubble.think = SUB_Remove;
bubble.classname = "bubble";
bubble.frame = 0;
bubble.cnt = 0;
setsize(bubble, '-8 -8 -8', '8 8 8');
};
void(vector org) ThorBoilWater =
{
local vector v;
local float f;
local float num_bubbles;
local entity e;
v=v_forward*600;
v=normalize(v);
if (self.rune_time < time)
num_bubbles=0;
else
num_bubbles=1000;
f=30;
while (f<600)
{
if ((pointcontents(org+(v*f))==CONTENT_WATER) ||
(pointcontents(org+(v*f))==CONTENT_SLIME))
{
if (num_bubbles<6)
{
ThorBoilWaterPoint(org+(v*f));
self.rune_time = time+1.5;
}
num_bubbles = num_bubbles + 1;
// SUCK: Hurt any enemies near the boiling water
e=findradius((v*f)+org, 75);
while (e!=world)
{
if ((e.classname == "player") &&
(e.team != self.team))
T_Damage(e, self, self, 5);
e=e.chain;
}
}
f=f+30;
}
};
void() W_FireLightning =
{
local vector org;
local float cells;
local entity kam;
local vector v;
local float r,q;
if (self.rune_num == ITEM_RUNE_GOLOM)
return;
if (self.ammo_cells < 1)
{
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
return;
}
if ((self.rune_num == ITEM_RUNE_THOR) && (self.rune_sound_start<time))
{
sound(self, CHAN_BODY, "ambience/thunder1.wav", 1, ATTN_NORM);
self.rune_sound_start=time+3.75;
}
// explode if under water
if ((self.waterlevel > 1) && (self.rune_num != ITEM_RUNE_THOR) &&
!((self.rune_num == ITEM_RUNE_HERMES) && (self.last_flight_watertype==CONTENT_EMPTY)) && (self.rune_num != ITEM_RUNE_POSEIDON))
{
cells = self.ammo_cells;
self.ammo_cells = 0;
W_SetCurrentAmmo ();
T_DischargeDamage (self, self, 35*cells, world);
return;
}
if (self.t_width < time)
{
playsound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
self.t_width = time + 0.6;
}
self.punchangle_x = -2;
if (self.rune_num != ITEM_RUNE_THOR)
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
else if ((self.rune_num == ITEM_RUNE_POSEIDON) &&
(self.ammo_cells == 100))
{
self.currentammo = self.ammo_cells = self.ammo_cells - 4;
self.trident_time = time + 3;
}
org = self.origin + '0 0 16';
traceline (org, org + v_forward*600, TRUE, self);
// SUCK: Boil the water that the shaft touches, if it does.
if (self.rune_num == ITEM_RUNE_THOR)
ThorBoilWater(org);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
WriteEntity (MSG_BROADCAST, self);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
WriteCoord (MSG_BROADCAST, trace_endpos_x);
WriteCoord (MSG_BROADCAST, trace_endpos_y);
WriteCoord (MSG_BROADCAST, trace_endpos_z);
if (self.rune_num == ITEM_RUNE_THOR)
LightningDamage (self.origin, trace_endpos + v_forward*4, self, 25);
else if ((self.rune_num == ITEM_RUNE_POSEIDON) && (self.trident_time>time))
LightningDamage (self.origin, trace_endpos + v_forward*4, self, 60);
else
LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
};
//=============================================================================
void() GrenadeExplode =
{
if (self.owner.rune_num == ITEM_RUNE_SAMURAI)
T_RadiusDamage (self, self.owner, 30, world);
else
T_RadiusDamage (self, self.owner, 120, world);
// playsound (self, CHAN_WEAPON, "dog/ddeath.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
BecomeExplosion ();
};
void() GrenadeTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (other.takedamage == DAMAGE_AIM)
{
GrenadeExplode();
return;
}
playsound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
/*
================
W_FireGrenade
================
*/
void() W_FireGrenade =
{
local entity missile, mpuff;
if (self.rune_num == ITEM_RUNE_GOLOM)
return;
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
playsound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
self.punchangle_x = -2;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
missile.classname = "grenade";
// set missile speed
makevectors (self.v_angle);
if (self.v_angle_x)
missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
else
{
missile.velocity = aim(self, 10000);
missile.velocity = missile.velocity * 600;
missile.velocity_z = 200;
}
missile.avelocity = '300 300 300';
missile.angles = vectoangles(missile.velocity);
missile.touch = GrenadeTouch;
// set missile duration
missile.nextthink = time + missile.owner.grenade_time;
if (self.grenade_time != 2.5) self.grenade_time = 2.5;
missile.think = GrenadeExplode;
// playsound (self, CHAN_WEAPON, "dog/dsight.wav", 1, ATTN_NORM);
setmodel (missile, "progs/grenade.mdl");
// setmodel (missile, "progs/dog.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin);
};
//=============================================================================
void() spike_touch;
void() superspike_touch;
/*
===============
launch_spike
Used for both the player and the ogre
===============
*/
void(vector org, vector dir) launch_spike =
{
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
newmis.angles = vectoangles(dir);
newmis.touch = spike_touch;
newmis.classname = "spike";
newmis.think = SUB_Remove;
newmis.nextthink = time + 6;
if (self.rune_num != ITEM_RUNE_LOKI)
setmodel (newmis, "progs/spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
setorigin (newmis, org);
if (self.rune_num == ITEM_RUNE_WIND)
newmis.velocity = dir * 3000;
else
newmis.velocity = dir * 1000;
};
void() W_FireSuperSpikes =
{
local vector dir;
local entity old;
playsound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
self.attack_finished = time + 0.2 + self.balder_slowdown;
self.currentammo = self.ammo_nails = self.ammo_nails - 2;
dir = aim (self, 1000);
launch_spike (self.origin + '0 0 16', dir);
newmis.touch = superspike_touch;
if (self.rune_num != ITEM_RUNE_LOKI)
setmodel (newmis, "progs/s_spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
self.punchangle_x = -2;
if ((self.rune_num == ITEM_RUNE_VAMPIRE)||
(self.rune_num == ITEM_RUNE_IFRITE))
{
launch_spike(self.origin + '0 0 16', dir);
newmis.solid=SOLID_NOT;
newmis.nextthink=time+3;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
setmodel(newmis, "progs/w_spike.mdl");
else
setmodel(newmis, "progs/k_spike.mdl");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
}
else if (self.rune_num == ITEM_RUNE_PRIEST)
{
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+5;
newmis.touch=holy_touch;
newmis.velocity=newmis.velocity - (newmis.velocity * 0.1);
setmodel(newmis, "progs/s_bubble.spr");
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
}
};
void(float ox) W_FireSpikes =
{
local vector dir;
local entity old;
makevectors (self.v_angle);
if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
{
W_FireSuperSpikes ();
return;
}
if (self.ammo_nails < 1)
{
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
return;
}
playsound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
self.attack_finished = time + 0.2 + self.balder_slowdown;
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
dir = aim (self, 1000);
launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
if ((self.rune_num == ITEM_RUNE_VAMPIRE) ||
(self.rune_num == ITEM_RUNE_IFRITE))
{
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+3;
if (self.rune_num == ITEM_RUNE_VAMPIRE)
setmodel(newmis, "progs/w_spike.mdl");
else
setmodel(newmis, "progs/k_spike.mdl");
newmis.solid=SOLID_NOT;
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
}
else if (self.rune_num == ITEM_RUNE_PRIEST)
{
launch_spike(self.origin + '0 0 16', dir);
newmis.nextthink=time+5;
newmis.touch=holy_touch;
setmodel(newmis, "progs/s_bubble.spr");
newmis.velocity=newmis.velocity - (newmis.velocity * 0.1);
setsize(newmis, VEC_ORIGIN, VEC_ORIGIN);
}
self.punchangle_x = -2;
};
.float hit_z;
void() spike_touch =
{
local float rand;
if (other == self.owner)
return;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (9);
if (self.owner.rune_num == ITEM_RUNE_SAMURAI)
T_Damage (other, self, self.owner, 18);
else
T_Damage (other, self, self.owner, 9);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
if (self.classname == "wizspike")
WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
else if (self.classname == "knightspike")
WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
else
WriteByte (MSG_BROADCAST, TE_SPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
}
remove(self);
};
void() superspike_touch =
{
local float rand, f;
local vector v;
local string s;
if (other == self.owner)
return;
if (other.solid == SOLID_TRIGGER)
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
spawn_touchblood (18);
v=self.origin - other.origin;
f=vlen(v);
s=ftos(f);
v=other.origin - self.origin;
v=normalize(v);
s=vtos(v);
if (self.rune_num == ITEM_RUNE_SAMURAI)
T_Damage (other, self, self.owner, 36);
else
T_Damage (other, self, self.owner, 18);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
}
remove(self);
};
/*
===============================================================================
PLAYER WEAPON USE
===============================================================================
*/
void() W_SetCurrentAmmo =
{
player_run (); // get out of any weapon firing states
self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
if (self.weapon == IT_AXE)
{
self.currentammo = 0;
self.weaponmodel = "progs/v_axe.mdl";
self.weaponframe = 0;
}
else if (self.weapon == IT_HOOK)
{
self.currentammo = 0;
if (teamplay & TEAM_CAPTURE_CUSTOM)
self.weaponmodel = "progs/v_star.mdl";
else
self.weaponmodel = "progs/v_axe.mdl";
self.weaponframe = 0;
}
else if (self.weapon == IT_SHOTGUN)
{
self.currentammo = self.ammo_shells;
self.weaponmodel = "progs/v_shot.mdl";
self.weaponframe = 0;
self.items = self.items | IT_SHELLS;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
self.currentammo = self.ammo_shells;
self.weaponmodel = "progs/v_shot2.mdl";
self.weaponframe = 0;
self.items = self.items | IT_SHELLS;
}
else if (self.weapon == IT_NAILGUN)
{
self.currentammo = self.ammo_nails;
self.weaponmodel = "progs/v_nail.mdl";
self.weaponframe = 0;
self.items = self.items | IT_NAILS;
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
self.currentammo = self.ammo_nails;
self.weaponmodel = "progs/v_nail2.mdl";
self.weaponframe = 0;
self.items = self.items | IT_NAILS;
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
self.currentammo = self.ammo_rockets;
self.weaponmodel = "progs/v_rock.mdl";
self.weaponframe = 0;
self.items = self.items | IT_ROCKETS;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
self.currentammo = self.ammo_rockets;
self.weaponmodel = "progs/v_rock2.mdl";
self.weaponframe = 0;
self.items = self.items | IT_ROCKETS;
}
else if (self.weapon == IT_LIGHTNING)
{
self.currentammo = self.ammo_cells;
self.weaponmodel = "progs/v_light.mdl";
self.weaponframe = 0;
self.items = self.items | IT_CELLS;
}
else
{
self.currentammo = 0;
self.weaponmodel = "";
self.weaponframe = 0;
}
};
float() W_BestWeapon =
{
local float it;
it = self.items;
if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
return IT_LIGHTNING;
if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
return IT_SUPER_NAILGUN;
if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
return IT_SUPER_SHOTGUN;
if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
return IT_NAILGUN;
if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
return IT_SHOTGUN;
return IT_AXE;
};
float() W_CheckNoAmmo =
{
if (self.currentammo > 0)
return TRUE;
if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
return TRUE;
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
// drop the weapon down
return FALSE;
};
/*
============
W_Attack
An attack impulse can be triggered now
============
*/
void() player_axe1;
void() player_axeb1;
void() player_axec1;
void() player_axed1;
void() player_shot1;
void() player_nail1;
void() player_light1;
void() player_rocket1;
void() player_chain1;
void() player_chain3;
void() W_Attack =
{
local float r;
if (!W_CheckNoAmmo ())
return;
if (self.loki_possessed)
return;
if (self.rune_num == ITEM_RUNE_LOKI)
self.loki_forcevis = 1;
makevectors (self.v_angle); // calculate forward angle for velocity
self.show_hostile = time + 1; // wake monsters up
if (self.attack_finished > time)
return;
if (self.weapon == IT_AXE)
{
playsound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
r = random();
if (r < 0.25)
player_axe1 ();
else if (r<0.5)
player_axeb1 ();
else if (r<0.75)
player_axec1 ();
else
player_axed1 ();
// RUNE: rune of hell magic
if (self.rune_num == ITEM_RUNE_HASTE) {
self.attack_finished = time + 0.3 + self.balder_slowdown;
HasteSound();
} else
self.attack_finished = time + 0.5 + self.balder_slowdown;
}
else if (self.weapon == IT_SHOTGUN)
{
player_shot1 ();
W_FireShotgun ();
// RUNE: rune of hell magic
if (self.rune_num == ITEM_RUNE_HASTE) {
self.attack_finished = time + 0.3 + self.balder_slowdown;
HasteSound();
} else
self.attack_finished = time + 0.5 + self.balder_slowdown;
if ((self.rune_num == ITEM_RUNE_PRIEST) && (self.holy == 1))
self.attack_finished=time+0.2 + self.balder_slowdown;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
player_shot1 ();
W_FireSuperShotgun ();
// RUNE: rune of hell magic
if (self.rune_num == ITEM_RUNE_HASTE)
{
self.attack_finished = time + 0.4 + self.balder_slowdown;
HasteSound();
}
else
self.attack_finished = time + 0.7 + self.balder_slowdown;
}
else if (self.weapon == IT_NAILGUN)
{
player_nail1 ();
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
player_nail1 ();
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
player_rocket1();
W_FireGrenade();
// RUNE: rune of hell magic
if (self.rune_num == ITEM_RUNE_HASTE) {
self.attack_finished = time + 0.3 + self.balder_slowdown;
HasteSound();
} else
self.attack_finished = time + 0.6 + self.balder_slowdown;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
player_rocket1();
W_FireRocket();
// RUNE: rune of hell magic
if (self.rune_num == ITEM_RUNE_HASTE) {
self.attack_finished = time + 0.4 + self.balder_slowdown;
HasteSound();
} else
self.attack_finished = time + 0.8 + self.balder_slowdown;
}
else if (self.weapon == IT_LIGHTNING)
{
player_light1();
self.attack_finished = time + 0.1 + self.balder_slowdown;
playsound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
}
else if (self.weapon == IT_HOOK)
{
if (!self.hook_out)
player_chain1();
else
player_chain3();
self.attack_finished = time + 0.1 + self.balder_slowdown;
}
};
void() NotifyWeapon =
{
// if (self.weapon == IT_AXE)
// sprint(self, "Axe selected.\n");
// else if (self.weapon == IT_HOOK)
// sprint(self, "Grappling hook selected.\n");
};
void(float fl, float am) forge_ammo =
{
if (self.armorvalue<20)
{
clientmsg(self, "Not enough armor to forge ammo.\n");
return;
}
self.armorvalue = self.armorvalue - 20;
if ((fl == IT_SUPER_SHOTGUN) || (fl == IT_SHOTGUN))
self.ammo_shells = self.ammo_shells + 20;
if ((fl == IT_NAILGUN) || (fl == IT_SUPER_NAILGUN))
self.ammo_nails = self.ammo_nails + 20;
if ((fl == IT_GRENADE_LAUNCHER) || (fl == IT_ROCKET_LAUNCHER))
self.ammo_rockets = self.ammo_rockets + 2;
if (fl == IT_LIGHTNING)
self.ammo_cells = self.ammo_cells + 10;
if (self.ammo_shells > 100) self.ammo_shells = 100;
if (self.ammo_nails > 200) self.ammo_nails = 200;
if (self.ammo_rockets > 100) self.ammo_rockets = 100;
if (self.ammo_cells > 100) self.ammo_cells = 100;
playsound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
};
void(float fl, float am) forge =
{
if (fl == IT_SUPER_SHOTGUN)
{
if (self.armorvalue<20)
{
clientmsg(self, "Not enough armor to forge that.\n");
return;
}
self.armorvalue = self.armorvalue - 20;
self.ammo_shells = self.ammo_shells + 20;
self.items = self.items | IT_SUPER_SHOTGUN;
if (self.ammo_shells > 100) self.ammo_shells = 100;
playsound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
}
else if (fl == IT_NAILGUN)
{
if (self.armorvalue<20)
{
clientmsg(self, "Not enough armor to forge that.\n");
return;
}
self.armorvalue = self.armorvalue - 20;
self.ammo_nails = self.ammo_nails + 25;
self.items = self.items | IT_NAILGUN;
if (self.ammo_nails > 200) self.ammo_nails = 200;
playsound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
}
else if (fl == IT_SUPER_NAILGUN)
{
if (self.armorvalue < 30)
{
clientmsg(self, "Not enough armor to forge that.\n");
return;
}
self.armorvalue = self.armorvalue - 30;
self.ammo_nails = self.ammo_nails + 50;
self.items = self.items | IT_SUPER_NAILGUN;
if (self.ammo_nails > 200) self.ammo_nails = 200;
playsound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
}
else if (fl == IT_GRENADE_LAUNCHER)
{
if (self.armorvalue < 50)
{
clientmsg(self, "Not enough armor to forge that.\n");
return;
}
self.armorvalue = self.armorvalue - 50;
self.ammo_rockets = self.ammo_rockets + 5;
self.items = self.items | IT_GRENADE_LAUNCHER;
if (self.ammo_rockets > 100) self.ammo_rockets = 100;
playsound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
}
else if (fl == IT_ROCKET_LAUNCHER)
{
if (self.armorvalue < 75)
{
clientmsg(self, "Not enough armor to forge that.\n");
return;
}
self.armorvalue = self.armorvalue - 75;
self.ammo_rockets = self.ammo_rockets + 10;
self.items = self.items | IT_ROCKET_LAUNCHER;
if (self.ammo_rockets > 100) self.ammo_rockets = 100;
playsound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
}
else if (fl == IT_LIGHTNING)
{
if (self.armorvalue < 75)
{
clientmsg(self, "Not enough armor to forge that.\n");
return;
}
self.armorvalue = self.armorvalue - 75;
self.ammo_cells = self.ammo_cells + 30;
self.items = self.items | IT_LIGHTNING;
if (self.ammo_cells > 100) self.ammo_cells = 100;
playsound (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
}
else return;
};
/*
============
W_ChangeWeapon
============
*/
void() W_ChangeWeapon =
{
local float it, am, fl, forged;
forged=0;
it = self.items;
am = 0;
if (self.impulse == 1) {
if (self.weapon == IT_AXE)
fl = IT_HOOK;
else
fl = IT_AXE;
} else if (self.impulse == 31) {
fl = IT_AXE;
} else if (self.impulse == 2 || self.impulse == 32) {
if ((self.weapon == IT_SHOTGUN) && (self.holy == 0))
self.holy=1;
else {
self.holy=0;
fl = IT_SHOTGUN;
if (self.ammo_shells < 1)
am = 1;
}
} else if (self.impulse == 3 || self.impulse == 33) {
fl = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
am = 1;
} else if (self.impulse == 4 || self.impulse == 34) {
fl = IT_NAILGUN;
if (self.ammo_nails < 1)
am = 1;
} else if (self.impulse == 5) {
fl = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
am = 1;
} else if (self.impulse == 35) {
fl = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
am = 1;
} else if (self.impulse == 6 || self.impulse == 36) {
if (self.weapon != IT_GRENADE_LAUNCHER)
self.grenade_time=2.5;
else
{
if (self.grenade_time == 2.5)
{
sprint(self, "5 second one-shot grenade selected\n");
self.grenade_time=5;
}
else if (self.grenade_time == 5)
{
sprint(self, "10 second one-shot grenade selected\n");
self.grenade_time=10;
}
else if (self.grenade_time == 10)
{
sprint(self, "Normal (2.5 second) grenades selected\n");
self.grenade_time=2.5;
}
}
fl = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
} else if (self.impulse == 7 || self.impulse == 37) {
fl = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
} else if (self.impulse == 8 || self.impulse == 38) {
fl = IT_LIGHTNING;
if (self.ammo_cells < 1)
am = 1;
} else if (self.impulse == 22 || self.impulse == 39) {
fl = IT_HOOK;
}
self.impulse = 0;
if (!(self.items & fl))
{
// don't have the weapon or the ammo
if (self.rune_num == ITEM_RUNE_VULCAN)
{
forge(fl, am);
forged=1;
}
else
{
sprint (self, "no weapon.\n");
return;
}
}
if (am && (forged != 1))
{ // don't have the ammo
if ((self.rune_num == ITEM_RUNE_VULCAN) && (forged != 1))
{
forged=1;
forge_ammo(fl, am);
}
else
{
sprint (self, "not enough ammo.\n");
return;
}
}
if(!(self.items & fl))
return;
//McBain: save current weapon
// For explicit weapon selection, allow previous weapon and new weapon to be
// same except for IT_HOOK.
if (self.weapon != IT_HOOK || fl != IT_HOOK)
self.previous_weapon = self.weapon;
//
// set weapon, set ammo
//
self.weapon = fl;
if ((self.weapon == self.previous_weapon) &&
(self.rune_num == ITEM_RUNE_VULCAN) && (forged==0))
forge_ammo(fl, am);
NotifyWeapon();
W_SetCurrentAmmo ();
};
/*
============
CheatCommand
============
*/
void() CheatCommand =
{
if (deathmatch || coop)
return;
self.ammo_rockets = 100;
self.ammo_nails = 200;
self.ammo_shells = 100;
self.items = self.items |
IT_AXE |
IT_HOOK |
IT_SHOTGUN |
IT_SUPER_SHOTGUN |
IT_NAILGUN |
IT_SUPER_NAILGUN |
IT_GRENADE_LAUNCHER |
IT_ROCKET_LAUNCHER |
IT_KEY1 | IT_KEY2;
self.ammo_cells = 200;
self.items = self.items | IT_LIGHTNING;
self.weapon = IT_ROCKET_LAUNCHER;
self.impulse = 0;
W_SetCurrentAmmo ();
};
/*
============
CycleWeaponCommand
Go to the next weapon with ammo
============
*/
void() CycleWeaponCommand =
{
local float it, am, loop_count;
it = self.items;
self.impulse = 0;
//McBain: save current weapon
self.previous_weapon = self.weapon;
loop_count = 0;
while (1)
{
am = 0;
if (self.weapon == IT_LIGHTNING) {
self.weapon = IT_AXE;
} else if (self.weapon == IT_AXE) {
self.weapon = IT_HOOK;
} else if (self.weapon == IT_HOOK) {
self.weapon = IT_SHOTGUN;
if (self.ammo_shells < 1)
am = 1;
} else if (self.weapon == IT_SHOTGUN) {
self.weapon = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
am = 1;
} else if (self.weapon == IT_SUPER_SHOTGUN) {
self.weapon = IT_NAILGUN;
if (self.ammo_nails < 1)
am = 1;
} else if (self.weapon == IT_NAILGUN) {
self.weapon = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
am = 1;
} else if (self.weapon == IT_SUPER_NAILGUN) {
self.weapon = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
} else if (self.weapon == IT_GRENADE_LAUNCHER) {
self.weapon = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
} else if (self.weapon == IT_ROCKET_LAUNCHER) {
self.weapon = IT_LIGHTNING;
if (self.ammo_cells < 1)
am = 1;
}
if ( (it & self.weapon) && am == 0)
{
NotifyWeapon();
W_SetCurrentAmmo ();
return;
}
loop_count = loop_count + 1;
if (loop_count > 8)
return;
}
};
/*
============
CycleWeaponReverseCommand
Go to the prev weapon with ammo
============
*/
void() CycleWeaponReverseCommand =
{
local float it, am;
it = self.items;
self.impulse = 0;
//McBain: save current weapon
self.previous_weapon = self.weapon;
while (1)
{
am = 0;
if (self.weapon == IT_LIGHTNING)
{
self.weapon = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
self.weapon = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
}
else if (self.weapon == IT_GRENADE_LAUNCHER)
{
self.weapon = IT_SUPER_NAILGUN;
if (self.ammo_nails < 1)
am = 1;
}
else if (self.weapon == IT_SUPER_NAILGUN)
{
self.weapon = IT_NAILGUN;
if (self.ammo_nails < 1)
am = 1;
}
else if (self.weapon == IT_NAILGUN)
{
self.weapon = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
am = 1;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
self.weapon = IT_SHOTGUN;
if (self.ammo_shells < 1)
am = 1;
}
else if (self.weapon == IT_SHOTGUN)
{
self.weapon = IT_HOOK;
}
else if (self.weapon == IT_HOOK)
{
self.weapon = IT_AXE;
}
else if (self.weapon == IT_AXE)
{
self.weapon = IT_LIGHTNING;
if (self.ammo_cells < 1)
am = 1;
}
if ( (it & self.weapon) && am == 0)
{
NotifyWeapon();
W_SetCurrentAmmo ();
return;
}
}
};
//McBain: Here's the beef...
/*
============
PreviousWeaponCommand
============
*/
void() PreviousWeaponCommand =
{
local float fl, am;
self.impulse = 0;
am = 0;
fl = self.weapon;
self.weapon = self.previous_weapon;
self.previous_weapon = fl;
// this might not be the best method, but I'll be able to play sooner
if (self.weapon == IT_SHOTGUN || self.weapon == IT_SUPER_SHOTGUN) {
if (self.ammo_shells < 1)
am = 1;
}
else if (self.weapon == IT_NAILGUN || self.weapon == IT_SUPER_NAILGUN) {
if (self.ammo_nails < 1)
am = 1;
}
else if (self.weapon == IT_GRENADE_LAUNCHER || self.weapon == IT_ROCKET_LAUNCHER) {
if (self.ammo_rockets < 1)
am = 1;
}
else if (self.weapon == IT_LIGHTNING) {
if (self.ammo_cells < 1)
am = 1;
}
// ignore AXE & HOOK -- no ammo needed
if (am)
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
};
/*
============
ServerflagsCommand
Just for development
============
*/
void() ServerflagsCommand =
{
serverflags = serverflags * 2 + 1;
// ZOID: Bug fix
serverflags = (serverflags & 15);
};
//ZOID: Uhm, where am I?
void() PrintLocation =
{
local string p;
p = vtos(self.origin);
sprint(self, "You are at ");
sprint(self, p);
sprint(self, "\n");
};
/*
============
ImpulseCommands
============
*/
//ZOID: Note, changed it all to an if/else construct. No need to check
//remaining impulses if we have one already. Much cleaner and a tad
//more efficient. Using a non-existant impulse is still the worst case. :(
void() ImpulseCommands =
{
local entity e;
if ((self.needsreg == 2) && (self.impulse != 98))
checkregimpulse();
else if (self.accessparm) // admin functions
CheckAdminCmd();
else if ((self.impulse >= 1 && self.impulse <= 8) || self.impulse == 22 ||
(self.impulse >= 31 && self.impulse <= 40))
W_ChangeWeapon ();
else if (self.impulse == 10)
CycleWeaponCommand ();
else if (self.impulse == 11)
ServerflagsCommand ();
else if (self.impulse == 12)
CycleWeaponReverseCommand ();
//McBain: I picked 69 -- seems appropriate! I hope 69 hasn't been used in
// other add-ons. This is my first attempt at Quake C, and I hope I haven't
// violated any Quake C ettiquette. :(
else if (self.impulse == 69)
PreviousWeaponCommand ();
else if (self.impulse == 99)
PrintLocation();
else if (self.impulse == 98)
regimpulse();
// *TEAMPLAY*
// If we're allowed to drop items, enable impulse 20 and 21
else if ((teamplay & TEAM_DROP_ITEMS) && self.impulse == 20)
TossBackpack ();
else if ((teamplay & TEAM_DROP_ITEMS) && self.impulse == 21)
TossWeapon ();
// *Capture The Flag - Status report by Wonko
// Impulse 23 prints the current status of your flag and the
// enemy flag (summarizes the endless messages)
else if (self.impulse == 23)
TeamFlagStatusReport();
// SUCK: Drop rune.
else if (self.impulse == 24)
TossRune();
// *TEAMPLAY*
// Impulse 25 prints info about the current teamplay settings.
else if (self.impulse == 25)
TeamPrintSettings ();
// SUCK: Help
else if (self.impulse == 26)
PrintHelp();
// SUCK: Rune info
else if (self.impulse == 27)
RuneInfo();
else if (self.impulse == 28)
GroupPowerInfo();
// SUCK: Status bar toggle.
else if (self.impulse == 29)
{
if (self.status_time == -1)
self.status_time = time;
else
self.status_time = -1;
}
else if (self.impulse >=71 && self.impulse <= 77)
{
// 71 - SOMETHINGx200
// 72 - SOMETHINGx240
// 73 - SOMETHINGx400
// 74 - SOMETHINGx480
// 75 - SOMETHINGx600
// 76 - SOMETHINGx768
// 77 - SOMETHINGx1024
if (self.impulse == 71)
self.bottom_line = 12;
else if (self.impulse == 72)
self.bottom_line = 17;
else if (self.impulse == 73)
self.bottom_line = 37;
else if (self.impulse == 74)
self.bottom_line = 47;
else if (self.impulse == 75)
self.bottom_line = 62;
else if (self.impulse == 76)
self.bottom_line = 83;
else if (self.impulse == 77)
self.bottom_line = 115;
}
else if (self.impulse == 101)
PrintStats();
else if (self.impulse == 102)
self.bottom_line = self.bottom_line + 1;
else if (self.impulse == 103)
self.bottom_line = self.bottom_line - 1;
else if (self.impulse == 141)
e=identify_player(1);
else if (self.impulse == 111)
{
if (self.rune_num != ITEM_RUNE_LOKI)
return;
msg_entity=self;
if (self.loki_possessed)
{
WriteByte(MSG_ONE, 5);
WriteEntity(MSG_ONE, self);
self.loki_possessed=0;
}
else
{
e=identify_player(0);
if (e==world)
{
self.msg_center=1;
clientmsg(self, "No player to possess!\n");
return;
}
msg_entity=self;
WriteByte(MSG_ONE, 5);
WriteEntity(MSG_ONE, e);
self.loki_possessed=1;
self.loki_possession=e;
}
}
else
CheckAdminCmd();
self.impulse = 0;
};
/*
============
W_WeaponFrame
Called every frame so impulse events can be handled as well as possible
============
*/
void() W_WeaponFrame =
{
if (time < self.attack_finished)
return;
//ZOID: Only call ImpulseCommands() if needed! This saves a good chunk
//of cpu. 'profile' in console listed ImpulseCommands() as #1 user of
//cpu (instructions), adding this one line caused it to not even be in
//the top ten.
if (self.impulse)
ImpulseCommands ();
// check for attack
if (self.button0)
{
SuperDamageSound ();
W_Attack ();
}
};
/*
========
SuperDamageSound
Plays sound if needed
========
*/
void() SuperDamageSound =
{
// RUNE play super damage sound if player has Black Magic, too
if (self.super_damage_finished > time ||
(self.rune_num == ITEM_RUNE_DBLDMG) ||
(self.rune_num == ITEM_RUNE_MARS) &&
(self.weapon != IT_HOOK)) {
if (self.super_sound < time) {
self.super_sound = time + 1;
playsound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
}
}
if ((self.rune_num == ITEM_RUNE_WEREWOLF) && (self.rune_sound_start < time) && (self.weapon != IT_HOOK))
{
sound(self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_NORM);
self.rune_sound_start = time + 0.8;
}
else
if ((self.rune_num == ITEM_RUNE_VAMPIRE) && (self.rune_sound_start < time) && (self.weapon != IT_HOOK))
{
sound(self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_NORM);
self.rune_sound_start = time + 2.5;
}
return;
};
/*
========
RegenerationSound
Plays sound if needed
========
*/
void() RegenerationSound =
{
// RUNE play healing sound if player has Elder Magic
if (self.rune_num == ITEM_RUNE_REGEN) {
if (self.regeneration_sound < time) {
self.regeneration_sound = time + 1;
sound(self, CHAN_BODY, "items/r_item1.wav", 1, ATTN_NORM);
}
}
return;
};
/*
========
HasteSound
Plays sound if needed
========
*/
void() HasteSound =
{
// RUNE play haste (Chthon's roar) sound if player has Hell Magic
if (self.rune_num == ITEM_RUNE_HASTE) {
if (self.haste_sound < time) {
self.haste_sound = time + 2;
sound(self, CHAN_BODY, "boss1/sight1.wav", 1, ATTN_NORM);
}
}
return;
};